use std::fs::{self, File};
use std::io::{self, BufRead, BufReader};
use std::path::Path;
use std::process::{Command, Stdio, Child};
use std::thread;
use std::time::Duration;
use std::os::windows::process::CommandExt;
use std::sync::{Arc, Mutex};
use tauri::Window;
use crate::config::AppConfig;
use reqwest;

pub struct FrpSetup;

// 全局FRP进程句柄
static mut FRP_PROCESS: Option<Child> = None;

impl FrpSetup {
    #[allow(dead_code)]
    pub fn new() -> Self {
        Self
    }

    pub async fn download_and_install_frp(frp_dir: String, window: Window) -> Result<String, String> {
        // 发送日志事件
        let _ = window.emit("frp-log", "开始下载 FRP...");
        
        // 创建安装目录
        if !Path::new(&frp_dir).exists() {
            fs::create_dir_all(&frp_dir).map_err(|e| format!("创建目录失败: {}", e))?;
        }
        
        // 下载并安装 FRP
        Self::download_frp(&frp_dir, &window).await?;
        
        // 生成默认配置文件
        Self::generate_frp_config_from_settings(frp_dir.clone())?;
        
        // 更新配置
        let mut config = AppConfig::load()?;
        config.update_frp_path(frp_dir.clone(), true)?;
        
        Ok("FRP 安装完成".to_string())
    }

    async fn download_frp(frp_dir: &str, window: &Window) -> Result<(), String> {
        let download_url = "https://god-panel.oss-cn-beijing.aliyuncs.com/frp_0.63.0_windows_amd64.zip";
        let zip_path = format!("{}\\frp.zip", frp_dir);
        
        // 发送日志到前端
        let _ = window.emit("frp-log", "正在检查网络连接...");
        let _ = window.emit("frp-log", "连接到 FRP 下载服务器...");
        let _ = window.emit("frp-log", "开始下载 FRP...");
        
        // 下载文件
        let client = reqwest::Client::new();
        let response = client.get(download_url)
            .send()
            .await
            .map_err(|e| format!("下载失败: {}", e))?;
        
        if !response.status().is_success() {
            return Err(format!("HTTP错误: {}", response.status()));
        }
        
        let bytes = response.bytes().await
            .map_err(|e| format!("读取响应失败: {}", e))?;
        
        let _ = window.emit("frp-log", "下载进度: 100%");
        
        // 保存 ZIP 文件
        let _ = window.emit("frp-log", "正在保存文件...");
        fs::write(&zip_path, &bytes)
            .map_err(|e| format!("保存文件失败: {}", e))?;
        
        // 解压文件
        Self::extract_zip_file(&zip_path, frp_dir, window)?;
        
        // 删除 ZIP 文件
        let _ = window.emit("frp-log", "正在清理临时文件...");
        fs::remove_file(&zip_path)
            .map_err(|e| format!("删除ZIP文件失败: {}", e))?;
        
        let _ = window.emit("frp-log", "验证安装完整性...");
        
        // 验证关键文件是否存在
        let frpc_exe = format!("{}\\frpc.exe", frp_dir);
        if !Path::new(&frpc_exe).exists() {
            return Err("FRP 安装不完整，frpc.exe 文件缺失".to_string());
        }
        
        let _ = window.emit("frp-log", "FRP 安装完成！");
        Ok(())
    }

    fn extract_zip_file(zip_path: &str, extract_dir: &str, window: &Window) -> Result<(), String> {
        let _ = window.emit("frp-log", "正在解压文件...");
        
        let file = File::open(zip_path)
            .map_err(|e| format!("打开ZIP文件失败: {}", e))?;
        
        let mut archive = zip::ZipArchive::new(file)
            .map_err(|e| format!("读取ZIP文件失败: {}", e))?;
        
        for i in 0..archive.len() {
            let mut file = archive.by_index(i)
                .map_err(|e| format!("访问ZIP文件条目失败: {}", e))?;
            
            let outpath = Path::new(extract_dir).join(file.name());
            
            if file.name().ends_with('/') {
                fs::create_dir_all(&outpath)
                    .map_err(|e| format!("创建目录失败: {}", e))?;
            } else {
                if let Some(p) = outpath.parent() {
                    if !p.exists() {
                        fs::create_dir_all(p)
                            .map_err(|e| format!("创建父目录失败: {}", e))?;
                    }
                }
                
                let mut outfile = File::create(&outpath)
                    .map_err(|e| format!("创建文件失败: {}", e))?;
                io::copy(&mut file, &mut outfile)
                    .map_err(|e| format!("复制文件失败: {}", e))?;
            }
        }
        
        let _ = window.emit("frp-log", "文件解压完成");
        Ok(())
    }
    
    pub fn start_frp(frp_dir: String) -> Result<(), String> {
        
        let frpc_exe = format!("{}\\frpc.exe", frp_dir);
        let frpc_ini = format!("{}\\frpc.ini", frp_dir);
        
        if !Path::new(&frpc_exe).exists() {
            return Err("FRP 可执行文件不存在".to_string());
        }
        
        if !Path::new(&frpc_ini).exists() {
            return Err("FRP 配置文件不存在".to_string());
        }
        
        
        // 检查是否已经在运行
        if Self::is_frp_running() {
            return Err("FRP 已经在运行".to_string());
        }
        
        // 启动 FRP 进程
        let mut command = Command::new(&frpc_exe);
        command
            .arg("-c")
            .arg(&frpc_ini)
            .current_dir(&frp_dir)
            .stdout(Stdio::piped())
            .stderr(Stdio::piped())
            .creation_flags(0x08000000); // CREATE_NO_WINDOW
        
        
        match command.spawn() {
            Ok(child) => {
                
                // 保存进程句柄
                unsafe {
                    FRP_PROCESS = Some(child);
                }
                
                // 启动日志监控
                Self::start_frp_log_monitoring(frp_dir.clone());
                
                // 更新配置状态
                if let Ok(mut config) = AppConfig::load() {
                    let _ = config.set_frp_running(true);
                }
                Ok(())
            }
            Err(e) => {
                Err(format!("启动 FRP 失败: {}", e))
            }
        }
    }

    fn start_frp_log_monitoring(frp_dir: String) {
        thread::spawn(move || {
            let log_file = format!("{}\\frpc.log", frp_dir);
            
            // 如果日志文件不存在，创建一个空的
            if !Path::new(&log_file).exists() {
                let _ = File::create(&log_file);
            }
            
            // 获取当前文件大小，用于定位到文件末尾
            let mut last_size = fs::metadata(&log_file)
                .map(|m| m.len())
                .unwrap_or(0);
            
            loop {
                thread::sleep(Duration::from_millis(100)); // 每100ms检查一次
                
                if let Ok(metadata) = fs::metadata(&log_file) {
                    let current_size = metadata.len();
                    
                    // 如果文件大小增加了，读取新内容
                    if current_size > last_size {
                        if let Ok(file) = File::open(&log_file) {
                            let mut reader = BufReader::new(file);
                            
                            // 跳过已读取的内容
                            let mut buffer = Vec::new();
                            reader.read_until(b'\n', &mut buffer).ok();
                            
                            // 读取新内容
                            for line in reader.lines() {
                                if let Ok(line_content) = line {
                                    // 这里可以通过全局窗口实例发送日志
                                    // 暂时先打印到控制台
                                    println!("FRP Log: {}", line_content);
                                }
                            }
                        }
                        last_size = current_size;
                    }
                }
                
                // 检查FRP进程是否还在运行
                if !Self::is_frp_running() {
                    break;
                }
            }
        });
    }
    
    pub fn stop_frp() -> Result<(), String> {
        // 先尝试优雅地停止进程
        unsafe {
            if let Some(mut child) = FRP_PROCESS.take() {
                let _ = child.kill();
                let _ = child.wait();
            }
        }
        
        // 如果进程还在运行，强制终止
        let _output = Command::new("taskkill")
            .args(&["/f", "/im", "frpc.exe"])
            .creation_flags(0x08000000) // CREATE_NO_WINDOW
            .output();
        
        // 更新运行状态
        let mut config = AppConfig::load()?;
        config.set_frp_running(false)?;
        
        Ok(())
    }
    
    pub fn save_frp_config(frp_dir: String, config_content: String) -> Result<(), String> {
        let config_path = format!("{}\\frpc.ini", frp_dir);
        
        std::fs::write(&config_path, config_content)
            .map_err(|e| format!("保存配置文件失败: {}", e))?;
        
        Ok(())
    }

    pub fn generate_frp_config_from_settings(frp_dir: String) -> Result<(), String> {
        let config = AppConfig::load()?;
        let frp_config = config.get_frp_config_all();
        
        let mut config_content = String::new();
        
        // [common] 部分
        config_content.push_str("[common]\n");
        config_content.push_str(&format!("server_addr = {}\n", 
            frp_config.get("server_addr").unwrap_or(&"127.0.0.1".to_string())));
        config_content.push_str(&format!("server_port = {}\n", 
            frp_config.get("server_port").unwrap_or(&"7000".to_string())));
        
        if let Some(token) = frp_config.get("auth_token") {
            if !token.is_empty() {
                config_content.push_str(&format!("token = {}\n", token));
            }
        }
        config_content.push_str("\n");
        
        // 检查是否启用端口映射
        if let Some(enable_mapping) = frp_config.get("enable_mapping") {
            if enable_mapping == "true" {
                // SCUM 游戏端口 (UDP)
                config_content.push_str("[scum-game]\n");
                config_content.push_str("type = udp\n");
                config_content.push_str("local_ip = 127.0.0.1\n");
                config_content.push_str(&format!("local_port = {}\n", 
                    frp_config.get("local_udp_port").unwrap_or(&"7777".to_string())));
                config_content.push_str(&format!("remote_port = {}\n", 
                    frp_config.get("remote_udp_port").unwrap_or(&"7777".to_string())));
                config_content.push_str("\n");
                
                // SCUM 查询端口 (TCP)
                config_content.push_str("[scum-query]\n");
                config_content.push_str("type = tcp\n");
                config_content.push_str("local_ip = 127.0.0.1\n");
                config_content.push_str(&format!("local_port = {}\n", 
                    frp_config.get("local_tcp_port").unwrap_or(&"7779".to_string())));
                config_content.push_str(&format!("remote_port = {}\n", 
                    frp_config.get("remote_tcp_port").unwrap_or(&"7779".to_string())));
            }
        }
        
        let config_path = format!("{}\\frpc.ini", frp_dir);
        std::fs::write(&config_path, config_content)
            .map_err(|e| format!("保存配置文件失败: {}", e))?;
        
        Ok(())
    }

    pub fn is_frp_running() -> bool {
        // 检查frpc.exe进程是否在运行
        let output = Command::new("tasklist")
            .args(&["/FI", "IMAGENAME eq frpc.exe", "/FO", "CSV"])
            .creation_flags(0x08000000) // CREATE_NO_WINDOW
            .output();
        
        match output {
            Ok(output) => {
                let output_str = String::from_utf8_lossy(&output.stdout);
                // 如果输出包含frpc.exe，说明进程在运行
                output_str.contains("frpc.exe")
            }
            Err(_) => false
        }
    }
} 